<?php

namespace app\admin\model\workteam;

use think\Model;
use traits\model\SoftDelete;

class Project extends Model
{

    // 表名
    protected $name = 'workteam_project';
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    protected $deleteTime = 'delete_time';
    // 追加属性
    protected $append = [

    ];
    protected static function init()
    {
        self::event('after_insert', function ($row) {
            $title = \app\admin\model\workteam\Log::getTitle();
            \app\admin\model\workteam\Log::record($row->id, 0, $title ? $title : __("添加项目"),__("项目名称").":".$row['name']);
        });
        self::event('before_update', function ($row) {
            $changedData = $row->getChangedData();
            //处理金额和项目支出字段
            if (isset($changedData['expenses'])) unset($changedData['expenses']);

            if ($changedData) {
                $title = \app\admin\model\workteam\Log::getTitle();
                \app\admin\model\workteam\Log::record($row->id, 0, $title ? $title : __("修改项目"), $changedData);
            }
        });
    }

    public function getStatusList()
    {
        return ['-1' => __('关闭'),'1' => __('进行中'), '0' => __('未开始'), '2' => __('完成'), '3' => __('归档')];
    }

    public function getLevelList()
    {
        return ['1' => __('无优先级'), '2' => __('不重要'), '3' => __('次要'), '4' => __('主要'), '5' => __('紧急')];
    }

    protected function setCreateTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : ($value ? $value : null);
    }


    /**
     * 创建者
     */
    public function cadmin()
    {
        return $this->belongsTo("\\app\\admin\\model\\Admin", 'create_admin_id', 'id', []);
    }
    /**
     * 项目经理
     */
    public function padmin()
    {
        return $this->belongsTo("\\app\\admin\\model\\Admin", 'project_admin_id', 'id', []);
    }
    /**
     * 业务经理
     */
    public function sadmin()
    {
        return $this->belongsTo("\\app\\admin\\model\\Admin", 'sales_admin_id', 'id', []);
    }
    /**
     * 任务列表
     */
    public function tasks(){
        return $this->hasMany("\\app\\admin\\model\\workteam\\Task",'project_id');
    }
    /**
     * 附件
     * @return \think\model\relation\HasMany
     */
    public function files(){
        return $this->hasMany('\app\admin\model\workteam\Files','project_id');
    }

    /**
     * 项目燃尽图
     */
    public function burnHoursEchart($project){
        if(is_numeric($project)){
            $project=$this->find($project);
        }

        if (!$project) {
            $this->error =__("项目不存在");
            return false;
        }
        $taskModel=new  \app\admin\model\workteam\Task();

        $starttime=$project['start_time'];
        $endtime=$project['end_time'];
        // 生成查询的开始和结束时间，默认取30日
        $isnotrangeDate = empty($starttime) && empty($endtime);
        $nearly = '30';
        if ($isnotrangeDate) {
            $endtime = time();
            $nearly -= 1;
            $starttime = strtotime("-{$nearly} day");  // 最近30天日期
        } elseif ($starttime > $endtime) {
            $this->error =__('起始时间要小于终止时间');
            return false;
        }
        $totalseconds = $endtime - $starttime;;
        if ($totalseconds > 86400 * 30 * 2) {
            $format = '%Y-%m';
        } else {
            if ($totalseconds > 86400) {
                $format = '%Y-%m-%d';
            } else {
                $format = '%H:00';
            }
        }
        //完成任务工时
        $lists = $taskModel->where('complete_time', 'between time', [$starttime, $endtime])
            ->field('COUNT(*) AS nums, sum(get_hours) as hours, DATE_FORMAT(FROM_UNIXTIME(complete_time), "' . $format . '") AS add_date')
            ->group('add_date')
            ->where('status', 2)
            ->select();
        //安排任务工时，开始时间为准
        $unlists = $taskModel->where('start_time', 'between time', [$starttime, $endtime])
            ->field('COUNT(*) AS nums, sum(get_hours) as hours, DATE_FORMAT(FROM_UNIXTIME(start_time), "' . $format . '") AS add_date')
            ->group('add_date')
            ->where('status', '<>', -1)
            ->select();

        $column[]=__("开始");
        if ($totalseconds > 84600 * 30 * 2) {
            $starttime = strtotime('last month', $starttime);
            while (($starttime = strtotime('next month', $starttime)) <= $endtime) {
                $column[] = date('Y-m', $starttime);
            }
        } else {
            if ($totalseconds > 86400) {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("Y-m-d", $time);
                    $time += 86400;
                }
            } else {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("H:00", $time);
                    $time += 3600;
                }
            }
        }


        $c_count = $c_hours = $s_hours = $s_count = array_fill_keys($column, 0);
        //处理成递减工时
        $times_hours=$plan_hours=$project['plan_hours'];//计划工时
        $task_count=$project['task_count'];//安排任务数量
        $count_num=count($column);
        $times_avg=bcdiv($project['plan_hours'],$count_num,2);//平均每次工时

        foreach ($column as $key => $val){

            $c_hours[$val]=$plan_hours;
            $c_count[$val]=$task_count;
            $c_avg[$val]=$key==0?$times_hours:$times_hours-$times_avg;//合理预期工时
            $times_hours= $c_avg[$val];
            foreach ($lists as $k => $v) {
                if ($v['add_date']==$val){
                    $plan_hours=$plan_hours-$v['hours'];
                    $task_count=$task_count-$v['nums'];
                    $c_hours[$val]=$plan_hours;
                    $c_count[$val]=$task_count;
                    break;
                }

            }
        }


        $data = [
            'date' => array_keys($c_count),
            'data' => [
                __("剩余任务") => array_values($c_count),
                __("剩余工时") => array_values($c_hours),
                __("合理工时")=> array_values($c_avg),
            ],
        ];
        return $data;
    }


    /**
     * 项目完成
     * @param null $complete_time 完成时间戳
     * @param null $row
     * @return bool
     * @throws \think\Exception
     */
    public function complete($complete_time=null,$row=null){
        $row=$row?$row:$this;
        //如果项目不是未开始和进行中的，都不给标记完成
        if (!in_array($row->status, [1, 0])){
            $this->error= __('项目状态不正常。');
            return false;
        }
        //判断任务是否都完成,没有完成不能更改状态
        $taskmodel = new  \app\admin\model\workteam\Task();
        if ($taskmodel->where('project_id',$row->id)->where('status','in',[0,1])->count()){
            $this->error= __('项目还有未完成的任务。');
            return false;
        }
        \app\admin\model\workteam\Log::setTitle(__('完成项目'));
        $row->status = 2;
        $row->complete_time =$complete_time?$complete_time:time();
        $row->save();
        return  true;

    }

    /**
     * 归档项目
     * @param null $row
     * @return bool
     */
    public function guidang($row=null){
        $row=$row?$row:$this;
        if ($row->status!=2){
            $this->error= __('项目不是完成状态。');
            return false;
        }
        \app\admin\model\workteam\Log::setTitle(__('归档项目'));
        $row->status = 3;
        return $row->save();

    }


    /**
     * 分析项目的财务信息
     * @param $startDate
     * @param $endDate
     * @param null $owner_user_ids 项目经理IDs
     * @param null $project_ids 项目IDs
     * @param null $time_field 统计的时间字段
     * @return array|bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getProjectEchart($startDate, $endDate,$owner_user_ids=null, $project_ids = null,$time_field="complete_time")
    {

        // 生成查询的开始和结束时间，默认取30日
        !is_numeric($startDate) && $starttime = strtotime($startDate);
        !is_numeric($endDate) && $endtime = strtotime($endDate);
        $isnotrangeDate = empty($starttime) && empty($endtime);
        $nearly = '30';
        if ($isnotrangeDate) {
            $endtime = time();
            $nearly -= 1;
            $starttime = strtotime("-{$nearly} day");  // 最近30天日期
        } elseif ($starttime > $endtime) {
            $this->error = '起始时间要小于终止时间';
            return false;
        }
        $totalseconds = $endtime - $starttime;;
        if ($totalseconds > 86400 * 30 * 2) {
            $format = '%Y-%m';
        } else {
            if ($totalseconds > 86400) {
                $format = '%Y-%m-%d';
            } else {
                $format = '%H:00';
            }
        }
        $tempwhere = array();
        if ($owner_user_ids && is_numeric($owner_user_ids)) {
            $tempwhere['project_admin_id'] = $owner_user_ids;
        } elseif ($owner_user_ids && is_array($owner_user_ids)) {
            $tempwhere['project_admin_id'] = ['in', $owner_user_ids];
        }
        if ($project_ids && is_numeric($project_ids)) {
            $tempwhere['id'] = $project_ids;
        } elseif ($project_ids && is_array($project_ids)) {
            $tempwhere['id'] = ['in', $project_ids];

        }

        $lists = $this->where($tempwhere)->where($time_field, 'between time', [$starttime, $endtime])
            ->field('COUNT(*) AS nums, sum(price) as price, sum(expenses) as expenses, DATE_FORMAT(FROM_UNIXTIME('.$time_field.'), "' . $format . '") AS add_date')
            ->group('add_date')
            ->where('status', 2)
            ->select();



        if ($totalseconds > 84600 * 30 * 2) {
            $starttime = strtotime('last month', $starttime);
            while (($starttime = strtotime('next month', $starttime)) <= $endtime) {
                $column[] = date('Y-m', $starttime);
            }
        } else {
            if ($totalseconds > 86400) {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("Y-m-d", $time);
                    $time += 86400;
                }
            } else {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("H:00", $time);
                    $time += 3600;
                }
            }
        }


        $c_count = $c_price = $c_expenses = array_fill_keys($column, 0);

        foreach ($lists as $k => $v) {
            $c_count[$v['add_date']] = $v['nums'];//完成项目数量
            $c_price[$v['add_date']] = $v['price'];//项目金额
            $c_expenses[$v['add_date']] = $v['expenses'];//项目支出
        }


        $data = [
            'date' => array_keys($c_count),
            'data' => [
                __("完成项目") => array_values($c_count),
                __("项目金额") => array_values($c_price),
                __("支出金额") => array_values($c_expenses),

            ],
        ];
        return $data;
    }

    /**
     * 获取projectids
     * @param $startDate
     * @param $endDate
     * @param null $owner_user_ids 项目负责人
     * @param array $status 项目的状态
     * @return bool
     */
    public function getProjectIds($startDate, $endDate,$owner_user_ids=null,$status=null,$time_field="complete_time"){
        // 生成查询的开始和结束时间，默认取30日
        !is_numeric($startDate) && $starttime = strtotime($startDate);
        !is_numeric($endDate) && $endtime = strtotime($endDate);
        $isnotrangeDate = empty($starttime) && empty($endtime);
        $nearly = '30';
        if ($isnotrangeDate) {
            $endtime = time();
            $nearly -= 1;
            $starttime = strtotime("-{$nearly} day");  // 最近30天日期
        } elseif ($starttime > $endtime) {
            $this->error = '起始时间要小于终止时间';
            return false;
        }
        $tempwhere = array();
        if ($owner_user_ids && is_numeric($owner_user_ids)) {
            $tempwhere['project_admin_id'] = $owner_user_ids;
        } elseif ($owner_user_ids && is_array($owner_user_ids)) {
            $tempwhere['project_admin_id'] = ['in', $owner_user_ids];
        }

        if ($status && is_numeric($status)) {
            $tempwhere['status'] = $status;
        } elseif ($status && is_array($status)) {
            $tempwhere['status'] = ['in', $status];
        }

        if ($time_field){
            $this->where($time_field, 'between time', [$starttime, $endtime]);
        }
       return $this->where($tempwhere)->fetchSql(false)->column('id');

    }




}
